package com.gcb.common.utils;


import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.util.UriUtils;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;

@Slf4j
public class BDAPIUtil {
    /**
     * 默认ak
     * 选择了ak，使用IP白名单校验：
     * 根据您选择的AK已为您生成调用代码
     * 检测到您当前的ak设置了IP白名单校验
     * 您的IP白名单中的IP非公网IP，请设置为公网IP，否则将请求失败
     * 请在IP地址为xxxxxxx的计算发起请求，否则将请求失败
     */
    public static String requestGetAK(String strUrl, Map<String, String> param){
        try {
            if (strUrl == null || strUrl.length() <= 0 || param == null || param.size() <= 0) {
                return null;
            }

            StringBuffer queryString = new StringBuffer();
            queryString.append(strUrl);
            for (Map.Entry<?, ?> pair : param.entrySet()) {
                queryString.append(pair.getKey() + "=");
                //    第一种方式使用的 jdk 自带的转码方式  第二种方式使用的 spring 的转码方法 两种均可
                //    queryString.append(URLEncoder.encode((String) pair.getValue(), "UTF-8").replace("+", "%20") + "&");
                queryString.append(UriUtils.encode((String) pair.getValue(), "UTF-8") + "&");
            }

            if (queryString.length() > 0) {
                queryString.deleteCharAt(queryString.length() - 1);
            }

            java.net.URL url = new URL(queryString.toString());
            URLConnection httpConnection = (HttpURLConnection) url.openConnection();
            httpConnection.connect();

            InputStreamReader isr = new InputStreamReader(httpConnection.getInputStream());
            BufferedReader reader = new BufferedReader(isr);
            StringBuffer buffer = new StringBuffer();
            String line;
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            reader.close();
            isr.close();
            //判断是否调用成功
            JSONObject jsonObject = JSONUtil.parseObj(buffer.toString());
            String s = checkResultStatus(jsonObject);
            if (!s.equals("success")){
                return null;
            }else {
                return buffer.toString();
            }
        }catch (Exception e){
            log.error("调用百度地图API异常,异常原因:{}", e.getMessage());
            return null;
        }
    }

    private static String checkResultStatus(JSONObject result) {
        if (result.containsKey("status")) {
            int status = result.get("status", Integer.class);
            if (status == 0){
                return "success";
            }else {
                if (status == 1) {
                    log.error("调用百度API接口失败，失败原因：{}", "服务器内部错误(该服务响应超时或系统内部错误，请留下联系方式)");
                } else if (status == 2) {
                    log.error("调用百度API接口失败，失败原因：{}", "参数错误(坐标类型错误，location格式错误)");
                } else if (status == 10) {
                    log.error("调用百度API接口失败，失败原因：{}", "上传内容超过8M(Post上传数据不能超过8M)");
                } else if (status == 101) {
                    log.error("调用百度API接口失败，失败原因：{}", "AK参数不存在(请求消息没有携带AK参数)");
                } else if (status == 102) {
                    log.error("调用百度API接口失败，失败原因：{}", "MCODE参数不存在，mobile类型mcode参数必需(对于Mobile类型的应用请求需要携带mcode参数，该错误码代表服务器没有解析到mcode)");
                } else if (status == 200) {
                    log.error("调用百度API接口失败，失败原因：{}", "APP不存在，AK有误请检查再重试(根据请求的AK，找不到对应的APP)");
                } else if (status == 201) {
                    log.error("调用百度API接口失败，失败原因：{}", "APP被用户自己禁用，请在控制台解禁()");
                } else if (status == 202) {
                    log.error("调用百度API接口失败，失败原因：{}", "APP被管理员删除(恶意APP被管理员删除)");
                } else if (status == 203) {
                    log.error("调用百度API接口失败，失败原因：{}", "APP类型错误(当前API控制台支持Server(类型1), Mobile(类型2, 新版控制台区分为Mobile_Android(类型21)及Mobile_IPhone（类型22））及Browser（类型3），除此之外其他类型认为是APP类型错误)");
                } else if (status == 210) {
                    log.error("调用百度API接口失败，失败原因：{}", "APP IP校验失败(在申请SERVER类型应用的时候选择IP校验，需要填写IP白名单，如果当前请求的IP地址不在IP白名单或者不是0.0.0.0/0就认为IP校验失败)");
                } else if (status == 211) {
                    log.error("调用百度API接口失败，失败原因：{}", "APP SN校验失败(SERVER类型APP有两种校验方式IP校验和SN校验，当用户请求的SN和服务端计算出来的SN不相等的时候提示SN校验失败)");
                } else if (status == 220) {
                    log.error("调用百度API接口失败，失败原因：{}", "APP Referer校验失败(浏览器类型的APP会校验referer字段是否存且切在referer白名单里面，否则返回该错误码)");
                } else if (status == 230) {
                    log.error("调用百度API接口失败，失败原因：{}", "APP Mcode码校验失败(服务器能解析到mcode，但和数据库中不一致，请携带正确的mcode)");
                } else if (status == 240) {
                    log.error("调用百度API接口失败，失败原因：{}", " APP 服务被禁用(用户在API控制台中创建或设置某APP的时候禁用了某项服务，若需开通权限，可进入API控制台为AK勾选对应服务)");
                } else if (status == 250) {
                    log.error("调用百度API接口失败，失败原因：{}", " 用户不存在(根据请求的user_id, 数据库中找不到该用户的信息，请携带正确的user_id)");
                } else if (status == 251) {
                    log.error("调用百度API接口失败，失败原因：{}", " 用户被自己删除(该用户处于未激活状态)");
                } else if (status == 252) {
                    log.error("调用百度API接口失败，失败原因：{}", " 用户被管理员删除(恶意用户被加入黑名单)");
                }
                else if (status == 260) {
                    log.error("调用百度API接口失败，失败原因：{}", " 服务不存在(服务器解析不到用户请求的服务名称)");
                }
                else if (status == 261) {
                    log.error("调用百度API接口失败，失败原因：{}", " 服务被禁用(该服务已下线，请在控制台确认是否有该服务的权限)");
                }
                else if (status == 302) {
                    log.error("调用百度API接口失败，失败原因：{}", " 天配额超限，限制访问(配额超限，如果想增加配额请联系我们)");
                }
                else if (status == 401) {
                    log.error("调用百度API接口失败，失败原因：{}", " 当前并发量已经超过约定并发配额，限制访问(并发控制超限，请控制并发量或联系我们)");
                }
                return "error";
            }

        }
        return "error";
    }
}
